home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / Telnet 2.6.1d1 4⁄26⁄94 Folder / source / main / wdefpatch.c < prev    next >
Text File  |  1994-04-18  |  12KB  |  463 lines

  1. /*******************************************
  2.  
  3.     WDEF Patcher
  4.     Steve Falkenburg MacDTS
  5.     ©1991 Apple Computer
  6.     
  7.     This snippet shows how you can add a simple extra part to a WDEF without
  8.     writing an entire WDEF.  It also shows how to access the new part via
  9.     FindWindow().
  10.     
  11.     Roberto Avanzi (independent programmer), June 18, 1992
  12.     Added support for tracking the extra part, in a way similar to the one used
  13.     by the system.
  14.     given back to Apple as an enhanced snippet (mmmh, sounds quite absurd)
  15.     
  16.     6/1/92    SJF        fixed a5 problem in WDEF patch (StripAddress is glue, and a5 wasn't set up)
  17.     6/1/92    SJF        fixed varCode bug that made zoom boxes not work (masked out high 8 bits)
  18.     
  19. *******************************************/
  20.  
  21. #ifdef MPW
  22. #pragma segment 22
  23. #endif
  24.  
  25. #include "TelnetHeader.h"
  26. #include <GestaltEqu.h>
  27. #ifdef THINK_C
  28. #include <SysEqu.h>
  29. #endif
  30. #include "wind.h"
  31. #include "wdefpatch.proto.h"
  32.  
  33. static void drawicon(short id, Rect *dest);
  34.  
  35. /* 931112, ragge, NADA, KTH */
  36. static void drawSize(Rect *wSize, WindowPtr window);
  37.  
  38. /* add 2 to this when checking with FindWindow() ! */
  39.  
  40. #define kOurHit    32
  41.  
  42.  
  43. /* 
  44.  * this struct allows us to insert a WDEF patch safely.  It contains a jump instruction
  45.  * and stores the old handle to the WDEF
  46.  */
  47.  
  48. typedef struct {
  49.     short jmpInst;
  50.     ProcPtr patchAddr;
  51.     Handle oldAddr;
  52.     Boolean partState;    /* roberto avanzi jun 18 1992 */
  53.     long ourA5;
  54.     struct WindRec *tw;
  55. } WDEFPatch, *WDEFPatchPtr, **WDEFPatchHndl;
  56.  
  57.  
  58. /* 
  59.  * this installs the WDEF patch into a window 
  60.  */
  61. void PatchWindowWDEF (WindowPtr window, struct WindRec *tw)
  62. {
  63. #ifdef    __powerpc__
  64.     return;
  65. #else
  66.     WDEFPatchHndl wdefHndl;
  67.     WDEFPatchPtr wdefPatch;
  68.     Handle oldAddr;
  69.     unsigned long wdefEntry;
  70.     
  71.     wdefHndl = (WDEFPatchHndl)NewHandle(sizeof(WDEFPatch));
  72. #ifdef notdef
  73.     if (MemError() != noErr)
  74.         /* ... */
  75. #endif
  76.  
  77.     oldAddr = ((WindowPeek)window)->windowDefProc;
  78.     if (GetMMUMode()) // 32-bit
  79.         wdefEntry = (unsigned long)wdefHndl;
  80.     else
  81.         wdefEntry = (unsigned long)StripAddress(wdefHndl) | ((unsigned long)oldAddr&0xff000000);
  82.  
  83.     HLock((Handle)wdefHndl);
  84.     wdefPatch = *wdefHndl;
  85.     wdefPatch->oldAddr = oldAddr;
  86.     wdefPatch->jmpInst = 0x4ef9; /*JMP*/
  87.     wdefPatch->patchAddr = (ProcPtr)MyWDEFPatch;
  88.     wdefPatch->ourA5 = *(long *)CurrentA5;
  89.     wdefPatch->tw = tw;
  90.  
  91.     HUnlock((Handle)wdefHndl);
  92.  
  93.     ((WindowPeek)window)->windowDefProc = (Handle)wdefEntry;
  94. #endif
  95. }
  96.  
  97.  
  98. /* 
  99.  * RePatchWindowWDEF
  100.  * this adjusts the tw pointer for a patched window
  101.  * We have to do this since the tw for a window can change when other
  102.  * windows are killed.
  103.  */
  104. void RePatchWindowWDEF (WindowPtr window, struct WindRec *tw)
  105. {
  106. #ifdef __powerpc__
  107.     return;
  108. #else
  109.     WDEFPatchHndl wdPatch;
  110.  
  111.     wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc;
  112.     (**wdPatch).tw = tw;
  113. #endif
  114. }
  115.  
  116.  
  117. /*
  118.  * GetPatchStuffHandle
  119.  * This returns the handle to our patch block so we can release it
  120.  * when killing windows. The tw is verified to insure that this
  121.  * window is really patched.
  122.  */
  123. Handle GetPatchStuffHandle (WindowPtr window, struct WindRec *tw)
  124. {
  125. #ifdef __powerpc__
  126.     return (NULL);
  127. #else
  128.     WDEFPatchHndl wdPatch;
  129.  
  130.     wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc;
  131.     if ((**wdPatch).tw == tw)
  132.         return ((Handle)wdPatch);
  133.     else
  134.         return ((Handle)0);
  135. #endif
  136. }
  137.  
  138.  
  139. pascal long MyWDEFPatch (short varCode, WindowPtr window, short message, long param)
  140. {
  141. #ifdef __powerpc__
  142.     return 0;
  143. #else
  144.     WDEFPatchHndl wdPatch;
  145.     pascal long (*wdefProc)(short varCode,WindowPtr window,short message,long param);
  146.     Handle oldWDEF;
  147.     long result;
  148.     Rect ourRect,ourElementRect;
  149.     GrafPtr    savePort;
  150.     GrafPtr aPort;
  151.     RgnHandle aRgn;
  152.     Rect aRect;
  153.     struct WindRec *tw;
  154.     long appA5, saveA5;
  155.     
  156.     wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc;
  157.     appA5 = (**wdPatch).ourA5;
  158.     saveA5 = SetA5(appA5);
  159.  
  160.     ourRect = (**((WindowPeek)window)->strucRgn).rgnBBox;
  161.     /* our 16x16 rectangle */
  162.     SetRect(&ourElementRect,ourRect.right-42,ourRect.top+1,ourRect.right-26,ourRect.top+17);
  163.     
  164.     tw = (**wdPatch).tw;
  165.  
  166.     oldWDEF = (**wdPatch).oldAddr;
  167.     HLock(oldWDEF);
  168.     wdefProc = (void *)*oldWDEF;
  169.     wdefProc = (void *)StripAddress(wdefProc);
  170.  
  171.     /* 
  172.      * now, folks, WHY do I check it, u'll ask me ? Heh, it's a funny quirk in
  173.      * the sys WDEF (at least, sys 7's, dunno whattabout older ones) .
  174.      * Suppose You click once in the grow icon and DO NOT resize the window.
  175.      * (remember, just click and do not move the mouse in the meantime).
  176.      * Then you click on the added part. That part is tracked in the right way,
  177.      *                             *    BUT   *
  178.      * ALSO the zoom box gets hilited. Dunno why should happen, but It's a lot
  179.      * of FUN. Sadly, cannot find its place in any useful app. Therefore we
  180.      * do this check.
  181.      * APPLE says: if you write your own WDEF and receive unknown messages, do not
  182.      *             do anything. pass along and do NOTHING.
  183.      * APPLE does: we get something new ? therefore we process it anyway, just to
  184.      *             keep developers writing workarounds and keep their minds afresh.
  185.      * What else can we say ? Thanks !!!!! (Roberto Avanzi june 19, 1992)
  186.      */
  187.     if ( (message == wDraw) ? (((short)param) != kOurHit ) : true )
  188.         result = (wdefProc)(varCode,window,message,param);
  189.  
  190.     if (((WindowPeek)window)->visible)
  191.     if (((WindowPeek)window)->hilited)
  192.     {
  193.         switch (message) {
  194.             case wDraw:
  195.                 GetPort(&savePort);
  196.                 GetWMgrPort(&aPort);
  197.                 SetPort(aPort);
  198.                 aRgn = NewRgn();
  199.                 GetClip(aRgn);
  200.                 SetRect(&aRect,-32000,-32000,32000,32000);
  201.                 ClipRect(&aRect);
  202.                 switch ( (short) param ) {    // Roberto Avanzi 18-06-1992: support for 
  203.                                             // tracking of the new part
  204.                     case 0:
  205.                         (**wdPatch).partState = false;
  206.  
  207.                     case kOurHit:
  208.                         PenNormal();                            // draw our part
  209.     
  210.                          if (tw->edata != NULL) {
  211.                              if (tw->edata->encrypt_output || tw->edata->decrypt_input) {
  212.                                  /* 
  213.                                   * erase 18 x 11. This gives us a 1 pixel margin
  214.                                   * on the left and right, and matches the mask that
  215.                                   * we're using in our crsr resources.
  216.                                   */
  217.                                  InsetRect(&ourElementRect, -1, 0);
  218.                                  ourElementRect.top += 3;
  219.                                  ourElementRect.bottom -= 2;
  220.                                  EraseRect(&ourElementRect);
  221.                                  ourElementRect.top -= 3;
  222.                                  ourElementRect.bottom += 2;
  223.                                  InsetRect(&ourElementRect, 1, 0);
  224.                              }                        
  225.                              if (tw->edata->encrypt_output && tw->edata->decrypt_input)
  226.                                  drawicon(lockcrsr, &ourElementRect);
  227.                              else if (tw->edata->encrypt_output)
  228.                                  drawicon(rightcrsr, &ourElementRect);
  229.                              else if (tw->edata->decrypt_input)
  230.                                  drawicon(leftcrsr, &ourElementRect);
  231.                          }
  232.                         break;
  233.                         
  234.                     default:
  235.                         break;
  236.                 }
  237.                 SetClip(aRgn);
  238.                 DisposeRgn(aRgn);
  239.                 SetPort(savePort);
  240.                 break;
  241.  
  242.                 // removed this test so that one can move the window
  243.                 // also when clicking on the icon area.
  244.                 // 931112, ragge, NADA, KTH
  245. #ifdef NOTDEF
  246.             case wHit:
  247.                 hitPt = (Point *)¶m;                    // hit test our part
  248.                 if (PtInRect(*hitPt,&ourElementRect))
  249.                 {
  250.                     //result =  kOurHit;
  251.                 }
  252.                 break;
  253. #endif
  254.             
  255.             case wGrow:        /* 931112, ragge, NADA, KTH */
  256.                 drawSize((Rect *) param, window);
  257.                 break;
  258.  
  259.             default:
  260.                 break;
  261.         }    // switch
  262.     }    //    if hilited (otherwise we dont see the new box, addition by Roberto Avanzi)
  263.     HUnlock(oldWDEF);
  264.     
  265.     SetA5(saveA5);
  266.     
  267.     return result;
  268. #endif
  269. }
  270.  
  271.  
  272. /*
  273.  * drawicon
  274.  */
  275. void drawicon (short id, Rect *dest)
  276. {
  277.     long qdv;
  278.     Handle ih = 0;
  279.     Rect source_rect;
  280.     BitMap mask_bitmap;
  281.     GrafPtr local_port;
  282.     PixMap *pm;
  283.     Ptr colormap;
  284.     CCrsr *ccrsr;
  285.     BitMap src_bitmap;
  286.  
  287.     GetPort(&local_port);
  288.  
  289.     ih = GetResource ('crsr', id);                /* color cursor */
  290.     if (!ih)
  291.         return;
  292.     DetachResource(ih);        /* ... need to save handle somewhere ... */
  293.     HLock(ih);                /* ... to avoid reloading the resource all the time */
  294.  
  295.     /* 
  296.      * Set source Rect and intialize source BitMaps. 
  297.      * A few PixMap fields must be munged;
  298.      */
  299.     SetRect (&source_rect, 0, 0, 16, 16);
  300.     
  301.     ccrsr = (CCrsr *)(*ih);
  302.  
  303.     mask_bitmap.bounds = source_rect;
  304.     mask_bitmap.rowBytes = 2;
  305.     mask_bitmap.baseAddr = (Ptr)&ccrsr->crsrMask; /* (Ptr)(((Byte *)(*ih)) + 52); */
  306.     
  307.     /*
  308.      * if gestalt fails or no color quickdraw, just use the b/w bitmap.
  309.      */
  310.     if (Gestalt(gestaltQuickdrawVersion, &qdv) || ((qdv & gestalt32BitQD) == 0)) {
  311.         src_bitmap.bounds = source_rect;
  312.         src_bitmap.rowBytes = 2;
  313.         src_bitmap.baseAddr = (Ptr)&ccrsr->crsr1Data;
  314.         CopyBits(&src_bitmap, &(local_port->portBits), &source_rect, dest,
  315.                  srcCopy, nil);    
  316.     } else {
  317.         pm = (PixMap *) ((unsigned char *)ccrsr + (long)ccrsr->crsrMap);
  318.         pm->baseAddr = (Ptr) ((unsigned char *)ccrsr + (long)ccrsr->crsrData);
  319.             colormap = (Ptr) ((unsigned char *)ccrsr + (long)pm->pmTable);
  320.         pm->pmTable = (CTabHandle) &colormap;        /* handle to colormap */
  321.  
  322.         /* 
  323.          * Draw the crsr using its mask. 
  324.          * Do we need the mask ??? ...
  325.          */
  326.         CopyMask((BitMap *)pm, &mask_bitmap, &(local_port->portBits),
  327.                  &source_rect, &source_rect, dest);
  328.     }
  329.  
  330.     HUnlock(ih);
  331.     ReleaseResource((Handle)ih);
  332.     DisposHandle((Handle)ih);
  333. }
  334.  
  335. /* 931112, ragge, NADA, KTH */
  336. #define    HOFFSET    2
  337. #define VOFFSET    2
  338. static Rect gGrowTextBox;
  339. static Rect gGrowTextBoxInset;
  340. Boolean gDoGrowSize = false;
  341. static struct growSavedStruct {
  342.     Point charSize;
  343.     Point charInset;
  344.     Boolean eraseIt;
  345.  
  346.     PenState    savedPen;
  347.     short txFont;
  348.     Style txFace;
  349.     short txMode;
  350.     short txSize;
  351. } gGrowSaved;
  352.  
  353. /* 931112, ragge, NADA, KTH */
  354. void setupForGrow(WindowPtr window, short hCharInset, short vCharInset, short hCharSize, short vCharSize)
  355. {
  356. #ifdef __powerpc__
  357.     return;
  358. #else
  359.     GrafPtr    savedPort;
  360.     FontInfo fInfo;
  361.  
  362.     GetPort(&savedPort);
  363.     SetPort(window);
  364.         
  365.     gGrowSaved.charSize.h = hCharSize;
  366.     gGrowSaved.charSize.v = vCharSize;
  367.     gGrowSaved.charInset.h = hCharInset;
  368.     gGrowSaved.charInset.v = vCharInset;
  369.  
  370.     if(gGrowSaved.charSize.h == 0)    // don't want zero-div
  371.         gGrowSaved.charSize.h = 1;
  372.     if(gGrowSaved.charSize.v == 0)
  373.         gGrowSaved.charSize.v = 1;
  374.         
  375.     gGrowSaved.eraseIt = false;
  376.     
  377.     GetPenState(&gGrowSaved.savedPen);
  378.     
  379.     gGrowSaved.txFont = window->txFont;
  380.     gGrowSaved.txFace = window->txFace;
  381.     gGrowSaved.txMode = window->txMode;
  382.     gGrowSaved.txSize = window->txSize;
  383.  
  384.     PenNormal();
  385.     TextFont(1);
  386.     TextSize(9);
  387.     TextFace(0);
  388.     TextMode(srcCopy);
  389.     
  390.     GetFontInfo(&fInfo);
  391.  
  392.     gGrowTextBox.top = VOFFSET;
  393.     gGrowTextBox.left = HOFFSET;
  394.     gGrowTextBox.bottom = VOFFSET + fInfo.ascent + fInfo.descent + fInfo.leading + 3;    // Yes, 3!
  395.     gGrowTextBox.right = HOFFSET + StringWidth("\p000 * 000") + 6;
  396.     gGrowTextBoxInset = gGrowTextBox;
  397.     InsetRect(&gGrowTextBoxInset, 1, 1);
  398.     
  399.     gDoGrowSize = true;
  400.     
  401.     SetPort(savedPort);
  402. #endif
  403. }
  404.  
  405. /* 931112, ragge, NADA, KTH */
  406. void cleanupForGrow(WindowPtr window)
  407. {
  408. #ifdef __powerpc__
  409.     return;
  410. #else
  411.  
  412.     GrafPtr    savedPort;
  413.     GetPort(&savedPort);
  414.     SetPort(window);
  415.     
  416.     gDoGrowSize = false;
  417.     
  418.     InvalRect(&gGrowTextBox);
  419.     
  420.     SetPenState(&gGrowSaved.savedPen);
  421.     
  422.     window->txFont = gGrowSaved.txFont;
  423.     window->txFace = gGrowSaved.txFace;
  424.     window->txMode = gGrowSaved.txMode;
  425.     window->txSize = gGrowSaved.txSize;
  426.     
  427.     SetPort(savedPort);
  428. #endif
  429. }
  430.  
  431. /* 931112, ragge, NADA, KTH */
  432. void drawSize(Rect *wSize, WindowPtr window)
  433. {
  434.     unsigned char string[50], yValLen;
  435.     GrafPtr savedPort;
  436.     
  437.     if(!gDoGrowSize)
  438.         return;
  439.  
  440.     GetPort(&savedPort);
  441.     SetPort(window);
  442.     
  443.     if(!gGrowSaved.eraseIt) {
  444.         NumToString((wSize->right - wSize->left - 15 - gGrowSaved.charInset.h) / gGrowSaved.charSize.h, string);
  445.         string[++string[0]] = ' ';
  446.         string[++string[0]] = '*';
  447.         NumToString((wSize->bottom - wSize->top - 15 - gGrowSaved.charInset.v) / gGrowSaved.charSize.v, string + string[0] + 1);
  448.         yValLen = string[string[0] + 1];
  449.         string[++string[0]] = ' ';
  450.         string[0] += yValLen;
  451.         TextBox(string + 1, string[0], &gGrowTextBoxInset, 1);
  452.         FrameRect(&gGrowTextBox);
  453.     } else {
  454.         Rect rGlob = gGrowTextBox;
  455.         LocalToGlobal((Point *) &(rGlob.top));
  456.         LocalToGlobal((Point *) &(rGlob.bottom));
  457.     }
  458.     
  459.     gGrowSaved.eraseIt = !gGrowSaved.eraseIt;
  460.  
  461.     SetPort(savedPort);
  462. }
  463.